using namespace std;

#include <Ap.h>
#include <Ph.h>
#include <Pt.h>
#include <sys/neutrino.h>
#include <sys/slog.h>
#include <sys/slogcodes.h>

#include <vector>
#include <string>
#include <map>
#include <functional>

#include "defines.h"
#include "spider_exception.h"
#include "system_settings.h"

const string app_version="ver 1.5.1.1 ";

system_settings::system_settings() : 
	escalator_mode_text(ESCALATOR_MODES_COUNT),
	escalator_ready_text(ESCALATOR_STATES_COUNT),
	udku_mode_text(UDKU_MODES_COUNT),
	udku_type_text(UDKU_TYPES_COUNT),
	udku_position_text(UDKU_POSITIONS_COUNT),
	directions_text_engl(DIRECTIONS_COUNT),
	directions_text_russ(DIRECTIONS_COUNT),
	outer_states_text(OUTER_STATES_COUNT),
	start_days_modes_text_engl(START_DAYS_MODES_COUNT),
	start_days_modes_text_russ(START_DAYS_MODES_COUNT),
    parameters_in_messages_strings(PARAMETERS_NAMES_COUNT),
	devices_config_name("config.ini"),
	global_messages_name("global_messages.ini"),
	messages_types_name("messages_types.ini"),
	devices_types_name("devices_types.ini"),
	main_log_name("main.log"),
    dispatchers_name("dispatchers.ini"),
	routing_name("routing.ini"){
	
		escalator_mode_text[ESCALATOR_MODE_UNUSED]="Ошибка режима!!";
		escalator_mode_text[ESCALATOR_MODE_MAIN_DRIVE_AT_PANEL]="ГП со щита";
		escalator_mode_text[ESCALATOR_MODE_MAIN_DRIVE_AT_BEANCH_BOARD]="ГП с пульта";
		escalator_mode_text[ESCALATOR_MODE_MAIN_DRIVE_AT_REMOTE_CONTROL]="ГП с ДУ";
		escalator_mode_text[ESCALATOR_MODE_SMALL_DRIVE_AT_PANEL]="МП со щита";
		escalator_mode_text[ESCALATOR_MODE_SMALL_DRIVE_AT_BEANCH_BOARD]="МП с пульта";
		escalator_mode_text[ESCALATOR_MODE_TEST]="Тест";
		escalator_mode_text[ESCALATOR_MODE_BRAKING_OFF]="Растормаж.";
		escalator_mode_text[ESCALATOR_MODE_RUNNING_OUT]="Выбег";

		escalator_ready_text[ESCALATOR_STATE_MAIN_DRIVE_READY]="ГП готов";
		escalator_ready_text[ESCALATOR_STATE_SMALL_DRIVE_READY]="МП Готов";
		escalator_ready_text[ESCALATOR_STATE_TEST_READY]="Тест готов";
		escalator_ready_text[ESCALATOR_STATE_BRAKING_OFF_READY]="Раст. готов";
		escalator_ready_text[ESCALATOR_STATE_RUNNING_OUT_READY]="Выбег готов";
		escalator_ready_text[ESCALATOR_STATE_NOT_READY]="Не готов";
		escalator_ready_text[ESCALATOR_STATE_WORKING]="Блок-цепи норма";

		udku_mode_text[UDKU_MODE_GPSTOP]="СТОП";
		udku_mode_text[UDKU_MODE_GPUP]="ПОДЪЕМ";
		udku_mode_text[UDKU_MODE_GPDOWN]="СПУСК";
		udku_mode_text[UDKU_MODE_UP20]="Превышение скорости на 20%";
		udku_mode_text[UDKU_MODE_UP25]="Превышение скорости на 25%";
		udku_mode_text[UDKU_MODE_NOT7SEC]="НЕ останов через 7 сек";
		udku_mode_text[UDKU_MODE_BREAK]="ОПРОКИДЫВАНИЕ";
		udku_mode_text[UDKU_MODE_SAMOHOD]="САМОХОД";
		udku_mode_text[UDKU_MODE_BRAK0]="Нет сигнала Д0 ДКСЭ";
		udku_mode_text[UDKU_MODE_BRAK90]="Нет сигнала Д90 ДКСЭ";
		udku_mode_text[UDKU_MODE_BRAKALLES]="Нет сигналов с ДКСЭ";
		udku_mode_text[UDKU_MODE_BRAKKSR]="Нет контакта стыковки разъемов ДКСЭ";
		udku_mode_text[UDKU_MODE_UNUSED]="-";

		udku_type_text[UDKU_TYPE_LT_1]="ЛТ-1 0.75 м/с";
		udku_type_text[UDKU_TYPE_LT_2]="ЛТ-2 0.90 м/с";
		udku_type_text[UDKU_TYPE_LT_3]="ЛТ-3 0.90 м/с";
		udku_type_text[UDKU_TYPE_LT_4]="ЛТ-4 0.88 м/с";
		udku_type_text[UDKU_TYPE_LT_5]="ЛТ-5 0.90 м/с";
		udku_type_text[UDKU_TYPE_ET_2]="ЭТ-2 0.94 м/с";
		udku_type_text[UDKU_TYPE_ET_3]="ЭТ-3 0.94 м/с";
		udku_type_text[UDKU_TYPE_ET_5]="ЭТ-5 0.73 м/с";
		udku_type_text[UDKU_TYPE_EM_4]="ЭМ-4 0.94 м/с";
		udku_type_text[UDKU_TYPE_EM_5_5_S]="ЭМ-5.5С 0.94 м/с";
		udku_type_text[UDKU_TYPE_EM_5_5_T]="ЭМ-5.5Т 0.75 м/с";
		udku_type_text[UDKU_TYPE_ET_5_H]="ЭТ-5Х 0.73 м/с";
		udku_type_text[UDKU_TYPE_UNUSED]="-";

        udku_position_text[UDKU_POSITION_LEFT]="Левое";
        udku_position_text[UDKU_POSITION_RIGHT]="Правое";
        udku_position_text[UDKU_POSITION_UNUSED]="-";

		outer_states_text[ENABLED]="enabled";
		outer_states_text[DISABLED]="disabled";

		directions_text_engl[DIRECTION_STOP]="stop";
		directions_text_engl[DIRECTION_UP]="up";
		directions_text_engl[DIRECTION_DOWN]="down";
		directions_text_engl[DIRECTION_REVERSE]="reverse";

		directions_text_russ[DIRECTION_STOP]="СТОП";
		directions_text_russ[DIRECTION_UP]="ПОДЪЕМ";
		directions_text_russ[DIRECTION_DOWN]="СПУСК";
		directions_text_russ[DIRECTION_REVERSE]="РЕВЕРС";

		start_days_modes_text_russ[START_DAY_MODE_EVERYDAY]="ЕЖЕДНЕВНО";
		start_days_modes_text_russ[START_DAY_MODE_NEVER]="НИКОГДА";
		start_days_modes_text_russ[START_DAY_MODE_ODD]="НЕЧЕТНЫЕ";
		start_days_modes_text_russ[START_DAY_MODE_EVEN]="ЧЕТНЫЕ";

		start_days_modes_text_engl[START_DAY_MODE_EVERYDAY]="everyday";
		start_days_modes_text_engl[START_DAY_MODE_NEVER]="never";
		start_days_modes_text_engl[START_DAY_MODE_ODD]="odd";
		start_days_modes_text_engl[START_DAY_MODE_EVEN]="even";

        parameters_in_messages_strings[PARAMETER_NAME_BREAKING_PATH_VALUE]="%breaking_path_value%";
        parameters_in_messages_strings[PARAMETER_NAME_BLOCK_CIRCUT_NAME]="%block_circut_name%";
        parameters_in_messages_strings[PARAMETER_VALUE]="%parameter_value%";
        parameters_in_messages_strings[PARAMETER_NAME_DISPATCHER]="%dispatcher%";
        parameters_in_messages_strings[PARAMETER_NAME_STOP_CAUSE]="%stop_cause%";

	};

void system_settings::sys_message(const int type, const string mess_text)
{

string buffer;
buffer.reserve(app_version.size() +mess_text.size()+12);

	switch(type)
	{
		case system_settings::ERROR_MSG:
			buffer=app_version +"ERROR: ";
			buffer+=mess_text;
			vslogf(_SLOG_SETCODE(_SLOGC_SPIDER, 0), _SLOG_ERROR, buffer.c_str(), NULL);
			break;
		case system_settings::INFO_MSG:
			buffer=app_version +"INFO: ";
			buffer+=mess_text;
			vslogf(_SLOG_SETCODE(_SLOGC_SPIDER, 0), _SLOG_INFO, buffer.c_str(), NULL);
      		break;
		case system_settings::DEBUG_MSG:
			buffer=app_version +"DEBUG: ";
			buffer+=mess_text;			
			vslogf(_SLOG_SETCODE(_SLOGC_SPIDER, 0), _SLOG_DEBUG1, buffer.c_str(), NULL);
      		break;
      	default:
			buffer=app_version +"UNDEFINED: ";
			buffer+=mess_text;
			vslogf(_SLOG_SETCODE(_SLOGC_SPIDER, 0), _SLOG_ERROR, buffer.c_str(), NULL);
			break;
	}
}


word system_settings::crc(bytes buffer){

static byte g_CRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40
};

static byte g_CRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
0x40
};

	byte highCRC = 0xFF;
	byte lowCRC = 0xFF;
	word	 index;

	if ( buffer.empty()) return(0);

	for (vector<byte>::iterator iter= buffer.begin();
			iter!= buffer.end();
			iter++) {
		index = highCRC ^ *iter;
		highCRC = lowCRC ^ g_CRCHi[index];
		lowCRC = g_CRCLo[index];
	}

	return (highCRC << 8 | lowCRC);
};


byte system_settings::decode_to_binary_decimal_notation(byte binary_value_less_100) 
                  throw (spider_exception){
      if (binary_value_less_100>99) throw spider_exception("In decode_to_binary_decimal_notation binary_value_less_100>99");

      byte count_10=0;
      byte count_1;
      while ((binary_value_less_100 - count_10*10)>=10)
           count_10++;

     count_1=binary_value_less_100 - count_10*10;

    return (count_10<<4)|count_1;
};

